from django.db import models

DAYS_OF_WEEK = (
    (0, 'Monday'),
    (1, 'Tuesday'),
    (2, 'Wednesday'),
    (3, 'Thursday'),
    (4, 'Friday'),
    (5, 'Saturday'),
    (6, 'Sunday'),
)

class Building(models.Model):
  """A building on campus"""
  # The name as it appears on schedule.berkeley.edu
  shortname = models.CharField(max_length=50)
  # A name that we can give to this building
  name = models.CharField(max_length=50, blank=True, default='')
  # Center of the building
  lat = models.FloatField(null=True, blank=True)
  lng = models.FloatField(null=True, blank=True)
  # We might want to hide some buildings
  hidden = models.BooleanField(default=False)
  
  def __str__(self):
    return self.name if self.name else self.shortname
  
  class Meta:
    ordering = ['name']
    
    
class Room(models.Model):
  """A Room within a building"""
  # The building its in
  building = models.ForeignKey(Building)
  name = models.CharField(max_length=30)
  # In case we want to label specific rooms
  description = models.CharField(max_length=50, default='')
  # If we want to provide more refined geolocation
  lat = models.FloatField(null=True, blank=True)
  lng = models.FloatField(null=True, blank=True)
  # We might want to hide some rooms
  hidden = models.BooleanField(default=False)
  
  def __str__(self):
    return '%s %s' % (self.building, self.name)
    
  class Meta:
    ordering = ['building', 'name']
  
  
class TimeBlock(models.Model):
  """A 30 minute time block.  This is for making time searches faster."""
  # Verbose description
  description = models.CharField(max_length=30, default='')
  # Day of week.  Mon/Tue/Wed/Thu/Fri/Sat/Sun
  day = models.CharField(max_length=1, choices=DAYS_OF_WEEK)
  # Start and end time of the block
  start_time = models.TimeField()
  end_time = models.TimeField()
  
  def __str__(self):
    return self.description
    
  class Meta:
    ordering = ['day', 'start_time']
  

class Major(models.Model):
  """A single major or department"""
  # The names as given by schedule.berkeley.edu
  shortname = models.CharField(max_length=30, unique=True)
  longname = models.CharField(max_length=40)
  # A name that we make up, to look better
  name = models.CharField(max_length=40, default='')
  # An abbrivation that this major commonly goes by
  abbriviation = models.CharField(max_length=15, default='')
  
  def __str__(self):
    return self.name if self.name else self.longname
  
  class Meta:
    ordering = ['longname']
  

class Course(models.Model):
  """A single class, may contain many sections"""
  # The names given by schedule.berkeley.edu
  code = models.CharField(max_length=10)  # Also 'shortname' sometimes
  title = models.CharField(max_length=100) # Or 'longname'
  # Department of this course
  major = models.ForeignKey(Major)
  # Verbose description of the class, scraped from the general catalog
  description = models.TextField(default='')
  
  def __str__(self):
    return '%s %s' % (self.major.shortname, self.code)
    
  class Meta:
    ordering = ['major', 'code']
  
class Section(models.Model):
  """A single section.  Could be a lab, lecture, or discussion"""
  # Course control number, we can key by this
  ccn = models.IntegerField(null=True)
  # The course object associated with this section
  course = models.ForeignKey(Course)
  # What type of section is this? (Lecture/Lab/Discussion/etc)
  type = models.CharField(max_length=10)
  # Section number.  May contain characters
  number = models.CharField(max_length=20)
  # What building is it in?
  building = models.ForeignKey(Building, null=True)
  # Room number?
  room = models.ForeignKey(Room, null=True)
  # When is it?  We represent this using 30 minute TimeBlocks
  time_blocks = models.ManyToManyField(TimeBlock)
  # We'll also store the verbose version of the times
  time = models.CharField(max_length=20)
  # We want to get all the time block for a single day
  section_time_blocks = models.ManyToManyField('SectionTimeBlock')
  # Who's teaching?  (Will activate this later)
  instructor = models.CharField(max_length=30, null=True)
  
  def __str__(self):
    return '%s %s %s' % (self.course, self.number, self.type)
    
  class Meta:
    ordering = ['course', 'number']
    
    
class SectionTimeBlock(models.Model):
  """A set of time blocks coorisponding to a single day's section times.
  Mainly used since each section time block coorisponds to a comment thread."""
  # Verbose description (Eg. M 1-2P)
  description = models.CharField(max_length=15, default='')
  # Day of week.  Mon/Tue/Wed/Thu/Fri/Sat/Sun
  day = models.CharField(max_length=1, choices=DAYS_OF_WEEK)
  # Time blocks represented
  time_blocks = models.ManyToManyField(TimeBlock)
  # Where is this section(s)
  room = models.ForeignKey(Room)
  # Start and end time of the block
  start_time = models.TimeField()
  end_time = models.TimeField()
  
  def __str__(self):
    return '%s in %s ' % (self.description, self.room)
    
  class Meta:
    unique_together = ('room', 'day', 'start_time', 'end_time')
  
  
class Thread(models.Model):
  """A thread is lazy generated for every SectionTimeBlock per day.  Comments
  should attach to a thread."""
  created = models.DateField(auto_now_add=True)
  section_time_block = models.ForeignKey(SectionTimeBlock)
  
  def __str__(self):
    return '%s on %s' % (self.section_time_block, self.created)
  
class Comment(models.Model):
  """A comment, attached to a thread."""
  # When it was created
  created = models.DateTimeField(auto_now_add=True)
  # Thread that this comment belongs to
  thread = models.ForeignKey(Thread)
  # Who posted?
  name = models.CharField(max_length=30, default='Anonymous')
  # Content
  text = models.TextField()
  
  def __str__(self):
    '%s(%s): %s' % (thread, name, text)